// src/adapters/adapter_factory.rs

use async_trait::async_trait;
use std::collections::HashMap;
use anyhow::{Result, anyhow, Context};
use log::{info, warn, error, debug};
use serde::{Deserialize, Serialize};
use url::Url;

use crate::{
    interfaces::{DataSourceAdapter, DataSourceConnection},
    models::{DataSourceSchema, DataSourceType},
    config::{
        Settings, 
        HuaweiCloudConfig, 
        DatabaseConfig, 
        RestApiConfig,
        ScenarioConfigs
    },
};

use super::{
    huawei_cloud_adapter::HuaweiCloudAdapter,
    database_adapter::{DatabaseAdapter, DatabaseConfig as DbConfig},
    rest_api_adapter::{RestApiAdapter, RestApiConfig as ApiConfig},
};

/// 适配器工厂 - 统一创建和管理各种数据源适配器
pub struct AdapterFactory {
    /// 配置设置
    settings: Settings,
    /// 已创建的适配器缓存
    adapters: HashMap<String, Box<dyn DataSourceAdapter>>,
    /// 适配器注册表
    registry: AdapterRegistry,
    /// 场景配置
    scenarios: ScenarioConfigs,
}

/// 适配器注册表
#[derive(Debug, Clone)]
pub struct AdapterRegistry {
    /// 注册的适配器类型
    registered_adapters: HashMap<String, AdapterMetadata>,
    /// 适配器优先级
    adapter_priorities: HashMap<String, u32>,
    /// 场景到适配器的映射
    scenario_adapter_mapping: HashMap<String, Vec<String>>,
}

/// 适配器元数据
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AdapterMetadata {
    /// 适配器名称
    pub name: String,
    /// 适配器类型
    pub adapter_type: DataSourceType,
    /// 适配器类名
    pub class_name: String,
    /// 支持的协议
    pub supported_protocols: Vec<String>,
    /// 支持的数据格式
    pub supported_formats: Vec<String>,
    /// 是否启用
    pub enabled: bool,
    /// 适配器版本
    pub version: String,
    /// 适配器描述
    pub description: String,
    /// 配置要求
    pub config_requirements: Vec<ConfigRequirement>,
}

/// 配置要求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConfigRequirement {
    /// 配置键名
    pub key: String,
    /// 配置类型
    pub value_type: ConfigValueType,
    /// 是否必需
    pub required: bool,
    /// 默认值
    pub default_value: Option<serde_json::Value>,
    /// 配置描述
    pub description: String,
}

/// 配置值类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ConfigValueType {
    String,
    Integer,
    Boolean,
    Object,
    Array,
    Secret, // 敏感信息，如密码、token
}

/// 适配器创建结果
#[derive(Debug, Clone)]
pub struct AdapterCreationResult {
    /// 适配器实例
    pub adapter: Box<dyn DataSourceAdapter>,
    /// 适配器元数据
    pub metadata: AdapterMetadata,
    /// 创建状态
    pub status: AdapterCreationStatus,
    /// 警告信息
    pub warnings: Vec<String>,
    /// 创建时间
    pub created_at: chrono::DateTime<chrono::Utc>,
}

/// 适配器创建状态
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AdapterCreationStatus {
    Success,
    PartialSuccess(Vec<String>),
    ConfigurationError(String),
    ConnectionError(String),
    InitializationError(String),
}

/// 适配器工厂配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AdapterFactoryConfig {
    /// 是否启用适配器缓存
    pub enable_caching: bool,
    /// 缓存超时时间（秒）
    pub cache_timeout_secs: u64,
    /// 最大适配器实例数
    pub max_adapters: usize,
    /// 适配器健康检查间隔
    pub health_check_interval_secs: u64,
    /// 自动重试次数
    pub auto_retry_attempts: u32,
    /// 场景自动检测
    pub enable_scenario_auto_detection: bool,
}

impl AdapterFactory {
    /// 创建新的适配器工厂
    pub fn new(settings: Settings) -> Result<Self> {
        let registry = Self::initialize_registry()?;
        let scenarios = settings.scenarios.clone();
        
        Ok(Self {
            settings,
            adapters: HashMap::new(),
            registry,
            scenarios,
        })
    }
    
    /// 初始化适配器注册表
    fn initialize_registry() -> Result<AdapterRegistry> {
        let mut registry = AdapterRegistry {
            registered_adapters: HashMap::new(),
            adapter_priorities: HashMap::new(),
            scenario_adapter_mapping: HashMap::new(),
        };
        
        // 注册华为云IoT适配器
        registry.register_adapter(AdapterMetadata {
            name: "huawei_cloud".to_string(),
            adapter_type: DataSourceType::CloudIoT,
            class_name: "HuaweiCloudAdapter".to_string(),
            supported_protocols: vec,
            supported_formats: vec,
            enabled: true,
            version: "1.0.0".to_string(),
            description: "华为云工业物联网平台适配器".to_string(),
            config_requirements: vec![
                ConfigRequirement {
                    key: "base_url".to_string(),
                    value_type: ConfigValueType::String,
                    required: true,
                    default_value: Some("https://iot-api.cn-north-4.myhuaweicloud.com".into()),
                    description: "华为云API基础地址".to_string(),
                },
                ConfigRequirement {
                    key: "access_token".to_string(),
                    value_type: ConfigValueType::Secret,
                    required: true,
                    default_value: None,
                    description: "访问令牌".to_string(),
                },
                ConfigRequirement {
                    key: "project_id".to_string(),
                    value_type: ConfigValueType::String,
                    required: true,
                    default_value: None,
                    description: "项目ID".to_string(),
                },
            ],
        });
        
        // 注册数据库适配器
        registry.register_adapter(AdapterMetadata {
            name: "database".to_string(),
            adapter_type: DataSourceType::Database,
            class_name: "DatabaseAdapter".to_string(),
            supported_protocols: vec,
            supported_formats: vec,
            enabled: true,
            version: "1.0.0".to_string(),
            description: "通用数据库适配器".to_string(),
            config_requirements: vec![
                ConfigRequirement {
                    key: "connection_url".to_string(),
                    value_type: ConfigValueType::String,
                    required: true,
                    default_value: None,
                    description: "数据库连接URL".to_string(),
                },
                ConfigRequirement {
                    key: "max_connections".to_string(),
                    value_type: ConfigValueType::Integer,
                    required: false,
                    default_value: Some(10.into()),
                    description: "最大连接数".to_string(),
                },
            ],
        });
        
        // 注册REST API适配器
        registry.register_adapter(AdapterMetadata {
            name: "rest_api".to_string(),
            adapter_type: DataSourceType::RestApi,
            class_name: "RestApiAdapter".to_string(),
            supported_protocols: vec,
            supported_formats: vec,
            enabled: true,
            version: "1.0.0".to_string(),
            description: "RESTful API适配器".to_string(),
            config_requirements: vec![
                ConfigRequirement {
                    key: "base_url".to_string(),
                    value_type: ConfigValueType::String,
                    required: true,
                    default_value: None,
                    description: "API基础地址".to_string(),
                },
                ConfigRequirement {
                    key: "timeout_secs".to_string(),
                    value_type: ConfigValueType::Integer,
                    required: false,
                    default_value: Some(30.into()),
                    description: "请求超时时间".to_string(),
                },
            ],
        });
        
        // 设置适配器优先级
        registry.set_adapter_priority("huawei_cloud", 100);
        registry.set_adapter_priority("database", 90);
        registry.set_adapter_priority("rest_api", 80);
        
        // 设置场景映射
        registry.map_scenario_to_adapters("manufacturing", vec!["huawei_cloud", "database"]);
        registry.map_scenario_to_adapters("robotics", vec!["rest_api", "database"]);
        registry.map_scenario_to_adapters("supply_chain", vec!["database"]);
        registry.map_scenario_to_adapters("transportation", vec!["rest_api"]);
        registry.map_scenario_to_adapters("research_education", vec!["rest_api", "huawei_cloud"]);
        registry.map_scenario_to_adapters("public_utilities", vec!["huawei_cloud"]);
        registry.map_scenario_to_adapters("campus_operations", vec!["rest_api"]);
        
        Ok(registry)
    }
    
    /// 根据数据源类型创建适配器
    pub async fn create_adapter(
        &mut self,
        adapter_type: &str,
        connection_config: &serde_json::Value,
    ) -> Result<AdapterCreationResult> {
        info!("创建适配器: {}", adapter_type);
        
        // 检查适配器是否已存在缓存中
        if let Some(cached_adapter) = self.adapters.get(adapter_type) {
            info!("使用缓存的适配器: {}", adapter_type);
            return Ok(AdapterCreationResult {
                adapter: cached_adapter.clone(),
                metadata: self.registry.get_adapter_metadata(adapter_type)
                    .ok_or_else(|| anyhow!("适配器元数据未找到: {}", adapter_type))?,
                status: AdapterCreationStatus::Success,
                warnings: vec![],
                created_at: chrono::Utc::now(),
            });
        }
        
        // 验证配置
        let validation_result = self.validate_adapter_config(adapter_type, connection_config).await?;
        if !validation_result.is_valid {
            return Ok(AdapterCreationResult {
                adapter: Box::new(EmptyAdapter),
                metadata: AdapterMetadata::default(),
                status: AdapterCreationStatus::ConfigurationError(
                    validation_result.errors.join(", ")
                ),
                warnings: validation_result.warnings,
                created_at: chrono::Utc::now(),
            });
        }
        
        // 创建适配器实例
        let creation_result = self.create_adapter_instance(adapter_type, connection_config).await?;
        
        // 缓存适配器实例
        if creation_result.status.is_success() {
            self.adapters.insert(adapter_type.to_string(), creation_result.adapter.clone());
            info!("适配器创建成功并已缓存: {}", adapter_type);
        }
        
        Ok(creation_result)
    }
    
    /// 根据场景自动创建适配器
    pub async fn create_adapters_for_scenario(
        &mut self,
        scenario_name: &str,
    ) -> Result<Vec<AdapterCreationResult>> {
        info!("为场景创建适配器: {}", scenario_name);
        
        let adapter_names = self.registry.get_adapters_for_scenario(scenario_name);
        if adapter_names.is_empty() {
            return Err(anyhow!("场景没有配置适配器: {}", scenario_name));
        }
        
        let mut results = Vec::new();
        
        for adapter_name in adapter_names {
            let config = self.get_adapter_config_for_scenario(adapter_name, scenario_name).await?;
            let result = self.create_adapter(adapter_name, &config).await?;
            results.push(result);
        }
        
        info!("为场景 {} 创建了 {} 个适配器", scenario_name, results.len());
        Ok(results)
    }
    
    /// 根据连接字符串自动检测并创建适配器
    pub async fn create_adapter_from_connection_string(
        &mut self,
        connection_string: &str,
    ) -> Result<AdapterCreationResult> {
        info!("从连接字符串创建适配器: {}", connection_string);
        
        let (adapter_type, config) = self.detect_adapter_from_connection_string(connection_string).await?;
        self.create_adapter(&adapter_type, &config).await
    }
    
    /// 从连接字符串检测适配器类型
    async fn detect_adapter_from_connection_string(
        &self,
        connection_string: &str,
    ) -> Result<(String, serde_json::Value)> {
        if let Ok(url) = Url::parse(connection_string) {
            match url.scheme() {
                "https" | "http" if connection_string.contains("myhuaweicloud.com") => {
                    let config = serde_json::json!({
                        "base_url": connection_string,
                        "access_token": self.settings.huawei_cloud.access_token,
                        "project_id": self.settings.huawei_cloud.project_id,
                    });
                    Ok(("huawei_cloud".to_string(), config))
                }
                "postgresql" | "mysql" | "sqlite" => {
                    let config = serde_json::json!({
                        "connection_url": connection_string,
                        "max_connections": 10,
                    });
                    Ok(("database".to_string(), config))
                }
                "https" | "http" => {
                    let config = serde_json::json!({
                        "base_url": connection_string,
                        "timeout_secs": 30,
                    });
                    Ok(("rest_api".to_string(), config))
                }
                _ => Err(anyhow!("无法识别的连接字符串协议: {}", url.scheme())),
            }
        } else {
            Err(anyhow!("无效的连接字符串格式"))
        }
    }
    
    /// 创建适配器实例
    async fn create_adapter_instance(
        &self,
        adapter_type: &str,
        config: &serde_json::Value,
    ) -> Result<AdapterCreationResult> {
        let metadata = self.registry.get_adapter_metadata(adapter_type)
            .ok_or_else(|| anyhow!("适配器未注册: {}", adapter_type))?;
            
        let mut warnings = Vec::new();
        let mut adapter: Box<dyn DataSourceAdapter> = Box::new(EmptyAdapter);
        let mut status = AdapterCreationStatus::Success;
        
        match adapter_type {
            "huawei_cloud" => {
                let huawei_config: HuaweiCloudConfig = serde_json::from_value(config.clone())?;
                match HuaweiCloudAdapter::new(huawei_config) {
                    Ok(adapter_instance) => {
                        adapter = Box::new(adapter_instance);
                        info!("华为云适配器创建成功");
                    }
                    Err(e) => {
                        status = AdapterCreationStatus::InitializationError(e.to_string());
                        error!("华为云适配器创建失败: {}", e);
                    }
                }
            }
            "database" => {
                let db_config: DbConfig = serde_json::from_value(config.clone())?;
                match DatabaseAdapter::new(db_config) {
                    Ok(adapter_instance) => {
                        adapter = Box::new(adapter_instance);
                        info!("数据库适配器创建成功");
                    }
                    Err(e) => {
                        status = AdapterCreationStatus::InitializationError(e.to_string());
                        error!("数据库适配器创建失败: {}", e);
                    }
                }
            }
            "rest_api" => {
                let api_config: ApiConfig = serde_json::from_value(config.clone())?;
                match RestApiAdapter::new(api_config) {
                    Ok(adapter_instance) => {
                        adapter = Box::new(adapter_instance);
                        info!("REST API适配器创建成功");
                    }
                    Err(e) => {
                        status = AdapterCreationStatus::InitializationError(e.to_string());
                        error!("REST API适配器创建失败: {}", e);
                    }
                }
            }
            _ => {
                return Err(anyhow!("不支持的适配器类型: {}", adapter_type));
            }
        }
        
        Ok(AdapterCreationResult {
            adapter,
            metadata,
            status,
            warnings,
            created_at: chrono::Utc::now(),
        })
    }
    
    /// 验证适配器配置
    async fn validate_adapter_config(
        &self,
        adapter_type: &str,
        config: &serde_json::Value,
    ) -> Result<ConfigValidationResult> {
        let metadata = self.registry.get_adapter_metadata(adapter_type)
            .ok_or_else(|| anyhow!("适配器未注册: {}", adapter_type))?;
            
        let mut errors = Vec::new();
        let mut warnings = Vec::new();
        
        for requirement in &metadata.config_requirements {
            if let Some(config_value) = config.get(&requirement.key) {
                // 验证值类型
                if !self.validate_config_value_type(config_value, &requirement.value_type) {
                    errors.push(format!("配置项 {} 类型不匹配", requirement.key));
                }
            } else if requirement.required {
                errors.push(format!("必需配置项缺失: {}", requirement.key));
            }
        }
        
        // 检查未知的配置项
        if let serde_json::Value::Object(obj) = config {
            for key in obj.keys() {
                if !metadata.config_requirements.iter().any(|r| &r.key == key) {
                    warnings.push(format!("未知配置项: {}", key));
                }
            }
        }
        
        Ok(ConfigValidationResult {
            is_valid: errors.is_empty(),
            errors,
            warnings,
        })
    }
    
    /// 验证配置值类型
    fn validate_config_value_type(&self, value: &serde_json::Value, expected_type: &ConfigValueType) -> bool {
        match (value, expected_type) {
            (serde_json::Value::String(_), ConfigValueType::String) => true,
            (serde_json::Value::Number(_), ConfigValueType::Integer) => true,
            (serde_json::Value::Bool(_), ConfigValueType::Boolean) => true,
            (serde_json::Value::Object(_), ConfigValueType::Object) => true,
            (serde_json::Value::Array(_), ConfigValueType::Array) => true,
            (serde_json::Value::String(_), ConfigValueType::Secret) => true, // 密码也是字符串
            _ => false,
        }
    }
    
    /// 获取场景特定的适配器配置
    async fn get_adapter_config_for_scenario(
        &self,
        adapter_name: &str,
        scenario_name: &str,
    ) -> Result<serde_json::Value> {
        let base_config = match adapter_name {
            "huawei_cloud" => serde_json::to_value(&self.settings.huawei_cloud)?,
            "database" => {
                if let Some(db_config) = &self.settings.database {
                    serde_json::to_value(db_config)?
                } else {
                    return Err(anyhow!("数据库配置未设置"));
                }
            }
            "rest_api" => {
                // 为REST API创建基础配置
                serde_json::json!({
                    "base_url": format!("{}/api", self.settings.server.host),
                    "timeout_secs": 30,
                })
            }
            _ => return Err(anyhow!("不支持的适配器类型: {}", adapter_name)),
        };
        
        // 根据场景调整配置
        let scenario_config = self.get_scenario_specific_config(adapter_name, scenario_name);
        self.merge_configs(base_config, scenario_config)
    }
    
    /// 获取场景特定配置
    fn get_scenario_specific_config(&self, adapter_name: &str, scenario_name: &str) -> serde_json::Value {
        match (adapter_name, scenario_name) {
            ("huawei_cloud", "manufacturing") => serde_json::json!({
                "timeout_secs": 60, // 生产制造场景需要更长超时
            }),
            ("database", "supply_chain") => serde_json::json!({
                "max_connections": 20, // 供应链场景需要更多连接
            }),
            ("rest_api", "robotics") => serde_json::json!({
                "timeout_secs": 10, // 机器人场景需要快速响应
            }),
            _ => serde_json::Value::Object(serde_json::Map::new()),
        }
    }
    
    /// 合并配置
    fn merge_configs(&self, base: serde_json::Value, overlay: serde_json::Value) -> Result<serde_json::Value> {
        if let (serde_json::Value::Object(mut base_obj), serde_json::Value::Object(overlay_obj)) = (base, overlay) {
            for (key, value) in overlay_obj {
                base_obj.insert(key, value);
            }
            Ok(serde_json::Value::Object(base_obj))
        } else {
            Ok(base)
        }
    }
    
    /// 获取所有已注册的适配器
    pub fn get_registered_adapters(&self) -> Vec<&AdapterMetadata> {
        self.registry.get_all_adapters()
    }
    
    /// 获取支持的场景列表
    pub fn get_supported_scenarios(&self) -> Vec<&str> {
        self.registry.get_supported_scenarios()
    }
    
    /// 清理缓存
    pub fn clear_cache(&mut self) {
        self.adapters.clear();
        info!("适配器缓存已清理");
    }
    
    /// 获取工厂状态
    pub fn get_factory_status(&self) -> FactoryStatus {
        FactoryStatus {
            total_adapters: self.registry.registered_adapters.len(),
            active_adapters: self.adapters.len(),
            cached_adapters: self.adapters.len(),
            supported_scenarios: self.get_supported_scenarios().len(),
        }
    }
}

impl AdapterRegistry {
    /// 注册适配器
    pub fn register_adapter(&mut self, metadata: AdapterMetadata) {
        self.registered_adapters.insert(metadata.name.clone(), metadata);
    }
    
    /// 设置适配器优先级
    pub fn set_adapter_priority(&mut self, adapter_name: &str, priority: u32) {
        self.adapter_priorities.insert(adapter_name.to_string(), priority);
    }
    
    /// 映射场景到适配器
    pub fn map_scenario_to_adapters(&mut self, scenario: &str, adapters: Vec<&str>) {
        self.scenario_adapter_mapping.insert(
            scenario.to_string(),
            adapters.into_iter().map(|s| s.to_string()).collect()
        );
    }
    
    /// 获取适配器元数据
    pub fn get_adapter_metadata(&self, adapter_name: &str) -> Option<&AdapterMetadata> {
        self.registered_adapters.get(adapter_name)
    }
    
    /// 获取场景对应的适配器
    pub fn get_adapters_for_scenario(&self, scenario: &str) -> Vec<&str> {
        self.scenario_adapter_mapping.get(scenario)
            .map(|adapters| adapters.iter().map(|s| s.as_str()).collect())
            .unwrap_or_else(Vec::new)
    }
    
    /// 获取所有适配器
    pub fn get_all_adapters(&self) -> Vec<&AdapterMetadata> {
        self.registered_adapters.values().collect()
    }
    
    /// 获取支持的场景
    pub fn get_supported_scenarios(&self) -> Vec<&str> {
        self.scenario_adapter_mapping.keys().map(|s| s.as_str()).collect()
    }
}

impl AdapterCreationStatus {
    /// 检查创建是否成功
    pub fn is_success(&self) -> bool {
        matches!(self, AdapterCreationStatus::Success)
    }
}

/// 空适配器实现（用于错误处理）
struct EmptyAdapter;

#[async_trait]
impl DataSourceAdapter for EmptyAdapter {
    async fn connect(&self, _data_source_type: &str, _connection_string: &str) 
        -> Result<Box<dyn DataSourceConnection>> 
    {
        Err(anyhow!("空适配器不能连接"))
    }

    async fn extract_schema(&self) -> Result<DataSourceSchema> {
        Err(anyhow!("空适配器不能提取Schema"))
    }

    async fn test_connection(&self) -> Result<bool> {
        Ok(false)
    }

    fn get_supported_data_sources(&self) -> Vec<String> {
        Vec::new()
    }
}

/// 配置验证结果
#[derive(Debug, Clone)]
struct ConfigValidationResult {
    pub is_valid: bool,
    pub errors: Vec<String>,
    pub warnings: Vec<String>,
}

/// 工厂状态
#[derive(Debug, Clone, Serialize)]
pub struct FactoryStatus {
    pub total_adapters: usize,
    pub active_adapters: usize,
    pub cached_adapters: usize,
    pub supported_scenarios: usize,
}

impl Default for AdapterMetadata {
    fn default() -> Self {
        Self {
            name: "unknown".to_string(),
            adapter_type: DataSourceType::Unknown,
            class_name: "UnknownAdapter".to_string(),
            supported_protocols: Vec::new(),
            supported_formats: Vec::new(),
            enabled: false,
            version: "0.0.0".to_string(),
            description: "未知适配器".to_string(),
            config_requirements: Vec::new(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[tokio::test]
    async fn test_adapter_factory_creation() {
        let settings = Settings::default();
        let factory = AdapterFactory::new(settings).unwrap();
        
        assert!(!factory.get_registered_adapters().is_empty());
        assert!(!factory.get_supported_scenarios().is_empty());
    }
    
    #[tokio::test]
    async fn test_adapter_creation() {
        let settings = Settings::default();
        let mut factory = AdapterFactory::new(settings).unwrap();
        
        let config = serde_json::json!({
            "base_url": "https://iot-api.example.com",
            "access_token": "test_token",
            "project_id": "test_project",
        });
        
        let result = factory.create_adapter("huawei_cloud", &config).await;
        assert!(result.is_ok());
    }
    
    #[test]
    fn test_adapter_registry() {
        let mut registry = AdapterRegistry {
            registered_adapters: HashMap::new(),
            adapter_priorities: HashMap::new(),
            scenario_adapter_mapping: HashMap::new(),
        };
        
        let metadata = AdapterMetadata {
            name: "test_adapter".to_string(),
            adapter_type: DataSourceType::CloudIoT,
            class_name: "TestAdapter".to_string(),
            supported_protocols: vec!["http".to_string()],
            supported_formats: vec!["json".to_string()],
            enabled: true,
            version: "1.0.0".to_string(),
            description: "测试适配器".to_string(),
            config_requirements: Vec::new(),
        };
        
        registry.register_adapter(metadata);
        assert!(registry.get_adapter_metadata("test_adapter").is_some());
    }
}